//
// Created by baka on 2025/9/24.
//

#include "LED.h"
#include "cmsis_os.h"
#include "gpio.h"


osThreadId ledTaskHandle;
osMessageQId ledQueueHandle;

//LED_TEST_MODE 1为测试模式   2为工作模式
#define LED_TEST_MODE 2



void LED_TEST(void)
{
    LED_HandleTypeDef led = {.port = GPIOF, .pin = GPIO_PIN_10, .state = 1};
    led.state = 1;
    xQueueSend(ledQueueHandle,&led, 0);
    osDelay(1000);
    led.state = 0;
    xQueueSend(ledQueueHandle,&led, 0);
}




// 函数声明
void LED_Init(LED_HandleTypeDef* led);
void LED_Toggle(LED_HandleTypeDef* led);
void LED_On(LED_HandleTypeDef* led);
void LED_Off(LED_HandleTypeDef* led);
void LED_SetState(LED_HandleTypeDef* led, uint8_t state);
void LED_ALL_INIT(void);
void ledTask(void const * argument);


void led_task_init(void)
{
    osThreadDef(ledTask, ledTask, osPriorityNormal, 0, 64);
    ledTaskHandle = osThreadCreate(osThread(ledTask), NULL);
    osMessageQDef(ledQueue, 2, LED_HandleTypeDef);
    ledQueueHandle = osMessageCreate(osMessageQ(ledQueue), NULL);
}

#if LED_TEST_MODE == 1
void ledTask(void const * argument)
{
    //所有LED初始化
    LED_ALL_INIT();
    //用于接收队列的数据
    LED_HandleTypeDef LED = {.port = GPIOF, .pin = GPIO_PIN_10, .state = 1};
    for (;;)
    {
        LED_Toggle(&LED);
        osDelay(500);
    }
}
#elif LED_TEST_MODE == 2
void ledTask(void const * argument)
{
    //所有LED初始化
    LED_ALL_INIT();
    //用于接收队列的数据
    LED_HandleTypeDef LED;
    for (;;)
    {
        if (xQueueReceive(ledQueueHandle,&LED,portMAX_DELAY) == pdTRUE)
        {
            HAL_GPIO_WritePin(LED.port, LED.pin, LED.state);
        }
        LED_Toggle(&LED);
        osDelay(500);
    }
}
#endif



void LED_ALL_INIT(void)
{
    // 定义LED数组
    LED_HandleTypeDef leds[LED_NUM] = {
        { .port = GPIOF, .pin = GPIO_PIN_10, .state = 1 },
        { .port = GPIOF, .pin = GPIO_PIN_9, .state = 1 },
        { .port = GPIOF, .pin = GPIO_PIN_8, .state = 1 },
        { .port = GPIOE, .pin = GPIO_PIN_2, .state = 1 }
    };
    for (int i = 0; i < LED_NUM; i++) {
        LED_Init(&leds[i]);
    }
}









/****************无需修改******************************/
// 定义一个宏来启用GPIO时钟
#define ENABLE_GPIO_LED_CLK(port) \
do { \
if ((port) == GPIOA) { __HAL_RCC_GPIOA_CLK_ENABLE(); } \
else if ((port) == GPIOB) { __HAL_RCC_GPIOB_CLK_ENABLE(); } \
else if ((port) == GPIOC) { __HAL_RCC_GPIOC_CLK_ENABLE(); } \
else if ((port) == GPIOD) { __HAL_RCC_GPIOD_CLK_ENABLE(); } \
else if ((port) == GPIOE) { __HAL_RCC_GPIOE_CLK_ENABLE(); } \
else if ((port) == GPIOF) { __HAL_RCC_GPIOF_CLK_ENABLE(); } \
else if ((port) == GPIOG) { __HAL_RCC_GPIOG_CLK_ENABLE(); } \
else if ((port) == GPIOH) { __HAL_RCC_GPIOH_CLK_ENABLE(); } \
else if ((port) == GPIOI) { __HAL_RCC_GPIOI_CLK_ENABLE(); } \
else { /* 未知端口 */ } \
} while (0)


// 初始化LED
void LED_Init(LED_HandleTypeDef* led) {
    GPIO_InitTypeDef GPIO_InitStruct = {0};

    // 配置GPIO
    ENABLE_GPIO_LED_CLK(led->port);
    GPIO_InitStruct.Pin = led->pin;
    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
    HAL_GPIO_Init(led->port, &GPIO_InitStruct);

    HAL_GPIO_WritePin(led->port, led->pin, led->state);
}

// 切换LED状态
void LED_Toggle(LED_HandleTypeDef* led) {
    led->state = !led->state;
    HAL_GPIO_WritePin(led->port, led->pin, (led->state ? GPIO_PIN_SET : GPIO_PIN_RESET));
}

// 打开LED
void LED_On(LED_HandleTypeDef* led) {
    led->state = 1;
    HAL_GPIO_WritePin(led->port, led->pin, GPIO_PIN_SET);
}

// 关闭LED
void LED_Off(LED_HandleTypeDef* led) {
    led->state = 0;
    HAL_GPIO_WritePin(led->port, led->pin, GPIO_PIN_RESET);
}

// 设置LED状态
void LED_SetState(LED_HandleTypeDef* led, uint8_t state) {
    led->state = state;
    HAL_GPIO_WritePin(led->port, led->pin, (state ? GPIO_PIN_SET : GPIO_PIN_RESET));
}


/****************无需修改******************************/
